/**
 * 错误处理和日志管理器
 * 统一处理应用中的错误、异常和日志记录
 */

import stateManager, { STATE_TYPES, setState } from './stateManager.js'
import { notifySystem } from './notificationManager.js'

/**
 * 错误级别枚举
 */
export const ERROR_LEVELS = {
	DEBUG: 'debug',
	INFO: 'info',
	WARN: 'warn',
	ERROR: 'error',
	FATAL: 'fatal'
}

/**
 * 错误类型枚举
 */
export const ERROR_TYPES = {
	// 系统错误
	SYSTEM: 'system',
	NETWORK: 'network',
	STORAGE: 'storage',
	PERMISSION: 'permission',
	
	// 应用错误
	VALIDATION: 'validation',
	BUSINESS: 'business',
	UI: 'ui',
	NAVIGATION: 'navigation',
	
	// 游戏错误
	GAME_LOGIC: 'game_logic',
	TEST_ERROR: 'test_error',
	SCORE_ERROR: 'score_error',
	
	// 数据错误
	DATA_SYNC: 'data_sync',
	DATA_CORRUPTION: 'data_corruption',
	DATA_MIGRATION: 'data_migration',
	
	// 第三方错误
	API: 'api',
	PLUGIN: 'plugin',
	EXTERNAL: 'external'
}

/**
 * 日志类型枚举
 */
export const LOG_TYPES = {
	USER_ACTION: 'user_action',
	SYSTEM_EVENT: 'system_event',
	PERFORMANCE: 'performance',
	DEBUG: 'debug',
	ERROR: 'error',
	ANALYTICS: 'analytics'
}

/**
 * 错误处理器类
 */
class ErrorHandler {
	constructor() {
		this.errorQueue = []
		this.logQueue = []
		this.maxQueueSize = 1000
		this.isInitialized = false
		this.settings = {
			enabled: true,
			logLevel: ERROR_LEVELS.INFO,
			showUserErrors: true,
			autoClearLogs: true,
			maxLogAge: 7 * 24 * 60 * 60 * 1000, // 7天
			sendToServer: false,
			serverEndpoint: '',
			batchSize: 50,
			flushInterval: 30000, // 30秒
			includeStackTrace: true,
			includeDeviceInfo: true,
			includeUserInfo: false
		}
		
		this.init()
	}
	
	/**
	 * 初始化错误处理器
	 */
	init() {
		if (this.isInitialized) return
		
		this.loadSettings()
		this.setupGlobalErrorHandlers()
		this.setupAutoFlush()
		this.loadStoredLogs()
		this.isInitialized = true
		
		this.log(LOG_TYPES.SYSTEM_EVENT, ERROR_LEVELS.INFO, '错误处理器已初始化')
	}
	
	/**
	 * 加载设置
	 */
	loadSettings() {
		try {
			if (typeof uni !== 'undefined') {
				const saved = uni.getStorageSync('error_handler_settings')
				if (saved) {
					this.settings = { ...this.settings, ...saved }
				}
			}
		} catch (error) {
			console.error('加载错误处理器设置失败:', error)
		}
	}
	
	/**
	 * 保存设置
	 */
	saveSettings() {
		try {
			if (typeof uni !== 'undefined') {
				uni.setStorageSync('error_handler_settings', this.settings)
			}
		} catch (error) {
			console.error('保存错误处理器设置失败:', error)
		}
	}
	
	/**
	 * 设置全局错误处理器
	 */
	setupGlobalErrorHandlers() {
		// JavaScript错误处理
		if (typeof window !== 'undefined') {
			window.addEventListener('error', (event) => {
				this.handleError({
					type: ERROR_TYPES.SYSTEM,
					level: ERROR_LEVELS.ERROR,
					message: event.message,
					filename: event.filename,
					lineno: event.lineno,
					colno: event.colno,
					stack: event.error?.stack,
					timestamp: new Date().toISOString()
				})
			})
			
			// Promise rejection处理
			window.addEventListener('unhandledrejection', (event) => {
				this.handleError({
					type: ERROR_TYPES.SYSTEM,
					level: ERROR_LEVELS.ERROR,
					message: 'Unhandled Promise Rejection',
					reason: event.reason,
					stack: event.reason?.stack,
					timestamp: new Date().toISOString()
				})
			})
		}
		
		// uni-app错误处理
		if (typeof uni !== 'undefined') {
			uni.onError((error) => {
				this.handleError({
					type: ERROR_TYPES.SYSTEM,
					level: ERROR_LEVELS.ERROR,
					message: 'uni-app error',
					error: error,
					timestamp: new Date().toISOString()
				})
			})
			
			uni.onUnhandledRejection((error) => {
				this.handleError({
					type: ERROR_TYPES.SYSTEM,
					level: ERROR_LEVELS.ERROR,
					message: 'uni-app unhandled rejection',
					error: error,
					timestamp: new Date().toISOString()
				})
			})
		}
	}
	
	/**
	 * 设置自动刷新
	 */
	setupAutoFlush() {
		setInterval(() => {
			this.flush()
			this.cleanOldLogs()
		}, this.settings.flushInterval)
	}
	
	/**
	 * 加载存储的日志
	 */
	loadStoredLogs() {
		try {
			if (typeof uni !== 'undefined') {
				const errorLogs = uni.getStorageSync('error_logs')
				const systemLogs = uni.getStorageSync('system_logs')
				
				if (errorLogs && Array.isArray(errorLogs)) {
					this.errorQueue = errorLogs.slice(-this.maxQueueSize)
				}
				
				if (systemLogs && Array.isArray(systemLogs)) {
					this.logQueue = systemLogs.slice(-this.maxQueueSize)
				}
			}
		} catch (error) {
			console.error('加载存储日志失败:', error)
		}
	}
	
	/**
	 * 处理错误
	 * @param {Object} errorInfo - 错误信息
	 */
	handleError(errorInfo) {
		if (!this.settings.enabled) return
		
		// 增强错误信息
		const enhancedError = this.enhanceError(errorInfo)
		
		// 添加到错误队列
		this.addToErrorQueue(enhancedError)
		
		// 记录日志
		this.log(LOG_TYPES.ERROR, enhancedError.level, enhancedError.message, enhancedError)
		
		// 显示用户错误（如果需要）
		if (this.settings.showUserErrors && this.shouldShowToUser(enhancedError)) {
			this.showErrorToUser(enhancedError)
		}
		
		// 更新应用状态
		this.updateAppState(enhancedError)
		
		// 触发错误事件
		stateManager.emit('errorOccurred', enhancedError)
	}
	
	/**
	 * 增强错误信息
	 * @param {Object} errorInfo - 原始错误信息
	 * @returns {Object} 增强后的错误信息
	 */
	enhanceError(errorInfo) {
		const enhanced = {
			id: Date.now() + Math.random(),
			timestamp: new Date().toISOString(),
			level: errorInfo.level || ERROR_LEVELS.ERROR,
			type: errorInfo.type || ERROR_TYPES.SYSTEM,
			message: errorInfo.message || 'Unknown error',
			...errorInfo
		}
		
		// 添加设备信息
		if (this.settings.includeDeviceInfo) {
			enhanced.deviceInfo = this.getDeviceInfo()
		}
		
		// 添加用户信息
		if (this.settings.includeUserInfo) {
			enhanced.userInfo = this.getUserInfo()
		}
		
		// 添加应用状态
		enhanced.appState = this.getAppState()
		
		// 处理堆栈跟踪
		if (this.settings.includeStackTrace && enhanced.stack) {
			enhanced.stackTrace = this.parseStackTrace(enhanced.stack)
		}
		
		return enhanced
	}
	
	/**
	 * 添加到错误队列
	 * @param {Object} error - 错误对象
	 */
	addToErrorQueue(error) {
		this.errorQueue.push(error)
		
		// 限制队列大小
		if (this.errorQueue.length > this.maxQueueSize) {
			this.errorQueue = this.errorQueue.slice(-this.maxQueueSize)
		}
	}
	
	/**
	 * 记录日志
	 * @param {string} type - 日志类型
	 * @param {string} level - 日志级别
	 * @param {string} message - 日志消息
	 * @param {Object} data - 附加数据
	 */
	log(type, level, message, data = {}) {
		if (!this.settings.enabled) return
		
		// 检查日志级别
		if (!this.shouldLog(level)) return
		
		const logEntry = {
			id: Date.now() + Math.random(),
			timestamp: new Date().toISOString(),
			type,
			level,
			message,
			data: this.sanitizeData(data)
		}
		
		// 添加到日志队列
		this.logQueue.push(logEntry)
		
		// 限制队列大小
		if (this.logQueue.length > this.maxQueueSize) {
			this.logQueue = this.logQueue.slice(-this.maxQueueSize)
		}
		
		// 控制台输出
		this.consoleLog(logEntry)
	}
	
	/**
	 * 检查是否应该记录日志
	 * @param {string} level - 日志级别
	 * @returns {boolean} 是否应该记录
	 */
	shouldLog(level) {
		const levels = [ERROR_LEVELS.DEBUG, ERROR_LEVELS.INFO, ERROR_LEVELS.WARN, ERROR_LEVELS.ERROR, ERROR_LEVELS.FATAL]
		const currentLevelIndex = levels.indexOf(this.settings.logLevel)
		const logLevelIndex = levels.indexOf(level)
		
		return logLevelIndex >= currentLevelIndex
	}
	
	/**
	 * 控制台日志输出
	 * @param {Object} logEntry - 日志条目
	 */
	consoleLog(logEntry) {
		const { level, message, data } = logEntry
		
		switch (level) {
			case ERROR_LEVELS.DEBUG:
				console.debug(`[${logEntry.timestamp}] ${message}`, data)
				break
			case ERROR_LEVELS.INFO:
				console.info(`[${logEntry.timestamp}] ${message}`, data)
				break
			case ERROR_LEVELS.WARN:
				console.warn(`[${logEntry.timestamp}] ${message}`, data)
				break
			case ERROR_LEVELS.ERROR:
			case ERROR_LEVELS.FATAL:
				console.error(`[${logEntry.timestamp}] ${message}`, data)
				break
			default:
				console.log(`[${logEntry.timestamp}] ${message}`, data)
		}
	}
	
	/**
	 * 清理敏感数据
	 * @param {Object} data - 原始数据
	 * @returns {Object} 清理后的数据
	 */
	sanitizeData(data) {
		if (!data || typeof data !== 'object') return data
		
		const sensitiveKeys = ['password', 'token', 'secret', 'key', 'auth', 'credential']
		const sanitized = { ...data }
		
		Object.keys(sanitized).forEach(key => {
			if (sensitiveKeys.some(sensitive => key.toLowerCase().includes(sensitive))) {
				sanitized[key] = '[REDACTED]'
			}
		})
		
		return sanitized
	}
	
	/**
	 * 判断是否应该向用户显示错误
	 * @param {Object} error - 错误对象
	 * @returns {boolean} 是否显示
	 */
	shouldShowToUser(error) {
		// 系统级错误通常不显示给用户
		if (error.type === ERROR_TYPES.SYSTEM) return false
		
		// 致命错误总是显示
		if (error.level === ERROR_LEVELS.FATAL) return true
		
		// 业务错误和验证错误显示给用户
		return [ERROR_TYPES.BUSINESS, ERROR_TYPES.VALIDATION, ERROR_TYPES.UI].includes(error.type)
	}
	
	/**
	 * 向用户显示错误
	 * @param {Object} error - 错误对象
	 */
	showErrorToUser(error) {
		const userMessage = this.getUserFriendlyMessage(error)
		
		// 使用通知管理器显示错误
		notifySystem('操作失败', userMessage)
	}
	
	/**
	 * 获取用户友好的错误消息
	 * @param {Object} error - 错误对象
	 * @returns {string} 用户友好的消息
	 */
	getUserFriendlyMessage(error) {
		const messageMap = {
			[ERROR_TYPES.NETWORK]: '网络连接失败，请检查网络设置',
			[ERROR_TYPES.STORAGE]: '数据存储失败，请检查存储空间',
			[ERROR_TYPES.PERMISSION]: '权限不足，请检查应用权限设置',
			[ERROR_TYPES.VALIDATION]: '输入数据有误，请检查后重试',
			[ERROR_TYPES.BUSINESS]: '操作失败，请稍后重试',
			[ERROR_TYPES.API]: '服务暂时不可用，请稍后重试',
			[ERROR_TYPES.DATA_SYNC]: '数据同步失败，请检查网络连接',
			[ERROR_TYPES.GAME_LOGIC]: '游戏出现异常，请重新开始',
			[ERROR_TYPES.TEST_ERROR]: '测试过程中出现错误，请重试'
		}
		
		return messageMap[error.type] || error.message || '发生未知错误'
	}
	
	/**
	 * 更新应用状态
	 * @param {Object} error - 错误对象
	 */
	updateAppState(error) {
		// 更新错误统计
		const currentStats = stateManager.getState(STATE_TYPES.APP, 'errorStats') || {
			total: 0,
			byType: {},
			byLevel: {},
			lastError: null
		}
		
		currentStats.total++
		currentStats.byType[error.type] = (currentStats.byType[error.type] || 0) + 1
		currentStats.byLevel[error.level] = (currentStats.byLevel[error.level] || 0) + 1
		currentStats.lastError = {
			id: error.id,
			type: error.type,
			level: error.level,
			message: error.message,
			timestamp: error.timestamp
		}
		
		setState(STATE_TYPES.APP, 'errorStats', currentStats)
	}
	
	/**
	 * 获取设备信息
	 * @returns {Object} 设备信息
	 */
	getDeviceInfo() {
		try {
			if (typeof uni !== 'undefined') {
				const systemInfo = uni.getSystemInfoSync()
				return {
					platform: systemInfo.platform,
					model: systemInfo.model,
					system: systemInfo.system,
					version: systemInfo.version,
					appVersion: systemInfo.appVersion
				}
			}
		} catch (error) {
			console.warn('获取设备信息失败:', error)
		}
		
		return null
	}
	
	/**
	 * 获取用户信息
	 * @returns {Object} 用户信息
	 */
	getUserInfo() {
		const userState = stateManager.getState(STATE_TYPES.USER)
		return {
			id: userState?.id,
			level: userState?.level,
			isLoggedIn: userState?.isLoggedIn
		}
	}
	
	/**
	 * 获取应用状态
	 * @returns {Object} 应用状态
	 */
	getAppState() {
		const appState = stateManager.getState(STATE_TYPES.APP)
		return {
			currentPage: appState?.currentPage,
			isOnline: appState?.isOnline,
			version: appState?.version
		}
	}
	
	/**
	 * 解析堆栈跟踪
	 * @param {string} stack - 堆栈字符串
	 * @returns {Array} 解析后的堆栈
	 */
	parseStackTrace(stack) {
		if (!stack) return []
		
		return stack.split('\n')
			.filter(line => line.trim())
			.map(line => {
				const match = line.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/)
				if (match) {
					return {
						function: match[1],
						file: match[2],
						line: parseInt(match[3]),
						column: parseInt(match[4])
					}
				}
				return { raw: line }
			})
	}
	
	/**
	 * 刷新日志到存储
	 */
	flush() {
		try {
			if (typeof uni !== 'undefined') {
				if (this.errorQueue.length > 0) {
					uni.setStorageSync('error_logs', this.errorQueue)
				}
				
				if (this.logQueue.length > 0) {
					uni.setStorageSync('system_logs', this.logQueue)
				}
			}
			
			// 发送到服务器（如果启用）
			if (this.settings.sendToServer && this.settings.serverEndpoint) {
				this.sendToServer()
			}
		} catch (error) {
			console.error('刷新日志失败:', error)
		}
	}
	
	/**
	 * 发送日志到服务器
	 */
	async sendToServer() {
		if (this.errorQueue.length === 0 && this.logQueue.length === 0) return
		
		try {
			const payload = {
				errors: this.errorQueue.slice(-this.settings.batchSize),
				logs: this.logQueue.slice(-this.settings.batchSize),
				deviceInfo: this.getDeviceInfo(),
				appInfo: this.getAppState(),
				timestamp: new Date().toISOString()
			}
			
			// 模拟API调用
			await new Promise((resolve, reject) => {
				setTimeout(() => {
					// 模拟成功
					resolve()
				}, 1000)
			})
			
			// 清空已发送的日志
			this.errorQueue = this.errorQueue.slice(this.settings.batchSize)
			this.logQueue = this.logQueue.slice(this.settings.batchSize)
			
		} catch (error) {
			console.error('发送日志到服务器失败:', error)
		}
	}
	
	/**
	 * 清理旧日志
	 */
	cleanOldLogs() {
		if (!this.settings.autoClearLogs) return
		
		const cutoffTime = Date.now() - this.settings.maxLogAge
		
		this.errorQueue = this.errorQueue.filter(error => 
			new Date(error.timestamp).getTime() > cutoffTime
		)
		
		this.logQueue = this.logQueue.filter(log => 
			new Date(log.timestamp).getTime() > cutoffTime
		)
	}
	
	/**
	 * 获取错误日志
	 * @param {Object} filters - 过滤条件
	 * @returns {Array} 错误日志列表
	 */
	getErrorLogs(filters = {}) {
		let logs = [...this.errorQueue]
		
		if (filters.type) {
			logs = logs.filter(log => log.type === filters.type)
		}
		
		if (filters.level) {
			logs = logs.filter(log => log.level === filters.level)
		}
		
		if (filters.startTime) {
			logs = logs.filter(log => new Date(log.timestamp) >= new Date(filters.startTime))
		}
		
		if (filters.endTime) {
			logs = logs.filter(log => new Date(log.timestamp) <= new Date(filters.endTime))
		}
		
		return logs.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
	}
	
	/**
	 * 获取系统日志
	 * @param {Object} filters - 过滤条件
	 * @returns {Array} 系统日志列表
	 */
	getSystemLogs(filters = {}) {
		let logs = [...this.logQueue]
		
		if (filters.type) {
			logs = logs.filter(log => log.type === filters.type)
		}
		
		if (filters.level) {
			logs = logs.filter(log => log.level === filters.level)
		}
		
		if (filters.startTime) {
			logs = logs.filter(log => new Date(log.timestamp) >= new Date(filters.startTime))
		}
		
		if (filters.endTime) {
			logs = logs.filter(log => new Date(log.timestamp) <= new Date(filters.endTime))
		}
		
		return logs.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
	}
	
	/**
	 * 清除所有日志
	 */
	clearAllLogs() {
		this.errorQueue = []
		this.logQueue = []
		
		try {
			if (typeof uni !== 'undefined') {
				uni.removeStorageSync('error_logs')
				uni.removeStorageSync('system_logs')
			}
		} catch (error) {
			console.error('清除日志失败:', error)
		}
	}
	
	/**
	 * 导出日志
	 * @returns {Object} 导出的日志数据
	 */
	exportLogs() {
		return {
			errors: this.errorQueue,
			logs: this.logQueue,
			settings: this.settings,
			exportTime: new Date().toISOString(),
			version: '1.0.0'
		}
	}
	
	/**
	 * 导入日志
	 * @param {Object} data - 导入的日志数据
	 */
	importLogs(data) {
		if (data.errors && Array.isArray(data.errors)) {
			this.errorQueue = [...this.errorQueue, ...data.errors]
			this.errorQueue = this.errorQueue.slice(-this.maxQueueSize)
		}
		
		if (data.logs && Array.isArray(data.logs)) {
			this.logQueue = [...this.logQueue, ...data.logs]
			this.logQueue = this.logQueue.slice(-this.maxQueueSize)
		}
		
		this.flush()
	}
	
	/**
	 * 更新设置
	 * @param {Object} newSettings - 新设置
	 */
	updateSettings(newSettings) {
		this.settings = { ...this.settings, ...newSettings }
		this.saveSettings()
	}
	
	/**
	 * 获取统计信息
	 * @returns {Object} 统计信息
	 */
	getStats() {
		const errorStats = {}
		const logStats = {}
		
		// 错误统计
		this.errorQueue.forEach(error => {
			errorStats[error.type] = (errorStats[error.type] || 0) + 1
		})
		
		// 日志统计
		this.logQueue.forEach(log => {
			logStats[log.type] = (logStats[log.type] || 0) + 1
		})
		
		return {
			errorCount: this.errorQueue.length,
			logCount: this.logQueue.length,
			errorStats,
			logStats,
			lastError: this.errorQueue[this.errorQueue.length - 1],
			lastLog: this.logQueue[this.logQueue.length - 1]
		}
	}
	
	/**
	 * 销毁错误处理器
	 */
	destroy() {
		this.flush()
		this.saveSettings()
		this.isInitialized = false
	}
}

// 创建全局实例
const errorHandler = new ErrorHandler()

// 便捷方法
export const handleError = (errorInfo) => {
	errorHandler.handleError(errorInfo)
}

export const logDebug = (message, data) => {
	errorHandler.log(LOG_TYPES.DEBUG, ERROR_LEVELS.DEBUG, message, data)
}

export const logInfo = (message, data) => {
	errorHandler.log(LOG_TYPES.SYSTEM_EVENT, ERROR_LEVELS.INFO, message, data)
}

export const logWarn = (message, data) => {
	errorHandler.log(LOG_TYPES.SYSTEM_EVENT, ERROR_LEVELS.WARN, message, data)
}

export const logError = (message, data) => {
	errorHandler.log(LOG_TYPES.ERROR, ERROR_LEVELS.ERROR, message, data)
}

export const logUserAction = (action, data) => {
	errorHandler.log(LOG_TYPES.USER_ACTION, ERROR_LEVELS.INFO, action, data)
}

export const logPerformance = (metric, data) => {
	errorHandler.log(LOG_TYPES.PERFORMANCE, ERROR_LEVELS.INFO, metric, data)
}

export const getErrorLogs = (filters) => {
	return errorHandler.getErrorLogs(filters)
}

export const getSystemLogs = (filters) => {
	return errorHandler.getSystemLogs(filters)
}

export const clearAllLogs = () => {
	errorHandler.clearAllLogs()
}

export const exportLogs = () => {
	return errorHandler.exportLogs()
}

export const importLogs = (data) => {
	errorHandler.importLogs(data)
}

export const updateErrorSettings = (settings) => {
	errorHandler.updateSettings(settings)
}

export const getErrorStats = () => {
	return errorHandler.getStats()
}

// 导出管理器实例
export default errorHandler